package controller.loginServlet.Check;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.ThreadLocalRandom;


@WebServlet("/captcha")
public class CaptchaServlet extends HttpServlet {
    private static final int WIDTH = 130;
    private static final int HEIGHT = 45;
    private static final String CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
    private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        resp.setHeader("Pragma", "No-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", 0);

        String code = generateCode(4);
        req.getSession().setAttribute("captcha", code);

        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // 抗锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 背景：浅蓝到白色渐变
        GradientPaint bg = new GradientPaint(0, 0, new Color(230, 235, 250),
                WIDTH, HEIGHT, new Color(255, 255, 255));
        g.setPaint(bg);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // 1️⃣ 底部干扰点（不影响文字）
        drawBackgroundNoise(g);

        // 2️⃣ 绘制验证码文字
        drawVerificationCode(g, code);

        // 3️⃣ 叠加曲线和前景干扰（轻度遮挡）
        drawForegroundNoise(g);

        g.dispose();
        resp.setContentType("image/png");
        ImageIO.write(image, "png", resp.getOutputStream());
    }

    /**
     * 绘制验证码文字
     */
    private void drawVerificationCode(Graphics2D g, String code) {
        int baseX = 18;
        int baseY = 30;

        for (int i = 0; i < code.length(); i++) {
            Font font = new Font("Arial", Font.BOLD, 26);
            g.setFont(font);

            // 亮蓝灰色字体，保证对比度
            Color textColor = new Color(
                    RANDOM.nextInt(40, 100),
                    RANDOM.nextInt(60, 120),
                    RANDOM.nextInt(150, 220)
            );
            g.setColor(textColor);

            int x = baseX + i * 28 + RANDOM.nextInt(3);
            int y = baseY + RANDOM.nextInt(4);

            double angle = RANDOM.nextDouble() * 0.25 - 0.12; // 控制角度
            AffineTransform transform = new AffineTransform();
            transform.rotate(angle, x, y);
            g.setTransform(transform);
            g.drawString(String.valueOf(code.charAt(i)), x, y);

            // 发光层（轻微）
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
            g.drawString(String.valueOf(code.charAt(i)), x + 1, y + 1);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));

            g.setTransform(new AffineTransform());
        }
    }

    /**
     * 背景噪点（底层）
     */
    private void drawBackgroundNoise(Graphics2D g) {
        for (int i = 0; i < 25; i++) {
            g.setColor(new Color(
                    RANDOM.nextInt(180, 240),
                    RANDOM.nextInt(180, 240),
                    RANDOM.nextInt(240, 255)
            ));
            g.fillRect(RANDOM.nextInt(WIDTH), RANDOM.nextInt(HEIGHT), 1, 1);
        }
    }

    /**
     * 前景遮挡（曲线 + 半透明点）
     */
    private void drawForegroundNoise(Graphics2D g) {
        // 半透明随机曲线
        g.setStroke(new BasicStroke(1.5f));
        for (int i = 0; i < 3; i++) {
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
            g.setColor(new Color(RANDOM.nextInt(100, 200),
                    RANDOM.nextInt(100, 200),
                    RANDOM.nextInt(180, 250)));

            int x1 = RANDOM.nextInt(WIDTH / 2);
            int y1 = RANDOM.nextInt(HEIGHT);
            int x2 = RANDOM.nextInt(WIDTH / 2, WIDTH);
            int y2 = RANDOM.nextInt(HEIGHT);
            int ctrlx = RANDOM.nextInt(WIDTH);
            int ctrly = RANDOM.nextInt(HEIGHT);

            QuadCurve2D curve = new QuadCurve2D.Float(x1, y1, ctrlx, ctrly, x2, y2);
            g.draw(curve);
        }

        // 半透明噪点（轻微遮挡文字）
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
        for (int i = 0; i < 50; i++) {
            g.setColor(new Color(
                    RANDOM.nextInt(150, 230),
                    RANDOM.nextInt(150, 230),
                    RANDOM.nextInt(150, 230)
            ));
            g.fillOval(RANDOM.nextInt(WIDTH), RANDOM.nextInt(HEIGHT), 2, 2);
        }
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
    }

    /**
     * 生成验证码
     */
    private String generateCode(int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(CHARS.charAt(RANDOM.nextInt(CHARS.length())));
        }
        return sb.toString();
    }
}
